package com.game.majiang.logic;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import com.game.majiang.algorithm.chexuan.GamePlayerInfo;
import com.game.majiang.config.CreateStructrue;
import com.game.majiang.config.DataManager;
import com.game.majiang.config.LogManager;
import com.game.majiang.logic.chexuan.ChexuanTableStatus;
import com.game.majiang.vo.UserVo;
import com.game.server.db.dao.XyGameLogDao;
import com.game.server.db.entity.TableUser;
import com.game.server.db.entity.TableUserInfo;
import com.game.server.db.entity.XyClubInfo;
import com.game.server.db.entity.XyUnionInfo;
import com.game.server.message.proto.out.BroadCastRuzuoRsp;
import com.game.server.message.proto.out.GameDelayedRsp;
import com.game.server.message.proto.out.RoomMasterOperateRsp;
import com.game.server.message.proto.out.RuzuoRsp;
import com.game.server.system.AbstractPlayer;
import com.game.server.system.AbstractTable;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

/**
 * @author 
 *
 */
@ToString
@Getter
public abstract class LogicTable extends AbstractTable {

	@Getter
	protected ChexuanTableStatus chexuanStatus = ChexuanTableStatus.WAIT;
	@Getter
	protected HashMap<Integer, GamePlayerInfo> mapRecord = new HashMap<Integer, GamePlayerInfo>();//实时战绩
	@Setter
	protected CreateStructrue create;
	private String pass = "";// 密码
	private ArrayList<String> listChat = new ArrayList<>();//聊天记录
	private String tableName = "";//桌子昵称
	@Getter
	protected ArrayList<Integer> listFreeSeat = new ArrayList<Integer>();//已使用免费留座玩家
	@Getter
	protected ArrayList<Integer> listKickPeopleUids = new ArrayList<Integer>();//被踢出玩家id
	@Setter
	private int unionid = 0;//联盟ID
	@Setter
	protected int clubid = 0;//俱乐部ID
	protected int gameCurrNumber = 0;//游戏当前局数
	protected int zhuangUid = 0;//
	protected int zhuangSeatNo = 0;//
	protected int operateTime = 0;//操作时间
	protected int operateUid = 0;
	@Getter
	protected int gameStartMinScore = 0;
	protected boolean forbidChat = true;//禁止聊天
	protected boolean bankerCloseBool = false;//房主关闭房间
	@Setter
	private int robotMaxId = 0;
	public abstract void timeEvent();
	public abstract void enterWatchPlayer(LogicClient client);//进入观战玩家
	public abstract void ready(LogicClient client);
	public abstract void toTableInfo(LogicClient client);
	public abstract void otherEnter(LogicPlayer player);
	public abstract boolean leave(LogicClient client);
	public abstract void tableClose();

	public LogicTable(int id) {
		super(id);

	}


	public synchronized boolean sitDown(LogicClient client, int seatNo) {
		RuzuoRsp rrsp = new RuzuoRsp();
		rrsp.setIsok(1);
		if(GetPlayerCount() < 8) {
			boolean haveBool = false;
			for (AbstractPlayer abPlayer : getPlayers()) {
				LogicPlayer player = (LogicPlayer) abPlayer;
				if(player.getSeatNo() == seatNo) {
					haveBool = true;
					break;
				}
			}
			if(!haveBool) {
				LogicPlayer player = (LogicPlayer) this.watchWar.getPlayer(client.getUserId());
				if(player == null) {
					rrsp.setIsok(2);
					client.Send(rrsp);
					return false;
				}
				player.seatNo = seatNo;
				player.setNextStandUpBool(false);
				player.setAutoOperateCount(0);
				player.setSetBoboTime(0);	
				if(player.getUsebobo() < this.gameStartMinScore) {
					player.setSetBoboTime(System.currentTimeMillis());	
				}

				this.watchWar.removePlayer(player.getUserId());
				addPlayer(player);
				otherEnter(player);
				BroadCastRuzuoRsp rsp = new BroadCastRuzuoRsp();
				rsp.setSeatNo(seatNo);
				rsp.setType(0);
				rsp.setUid(player.getUserId());
				BroadCast(rsp, 2);
				if(this.chexuanStatus == ChexuanTableStatus.READ) {
					bankerGameStart();
				}
				return true;
			}
		} else {
			client.Send(rrsp);
		}
		return false;
	}

	public synchronized boolean standUp(LogicClient client) {
		RuzuoRsp rrsp = new RuzuoRsp();
		rrsp.setIsok(1);
		LogicPlayer player = (LogicPlayer) getPlayer(client.getUserId());
		if(player != null ) {
			rrsp.setIsok(0);
			client.Send(rrsp);
			if(player.isReady()) {
				player.setNextStandUpBool(true);
			} else {
				player.setNextStandUpBool(false);
				removePlayer(player.getUserId());
				this.watchWar.addPlayer(player);
				BroadCastRuzuoRsp rsp = new BroadCastRuzuoRsp();
				rsp.setSeatNo(player.seatNo);
				rsp.setType(1);
				rsp.setUid(player.getUserId());
				BroadCast(rsp, 2);
				if(player.isBankerKickPeopleBool()) {
					if(leave(client) && client.isLost()) {
						client.Close();
					}
				}
			}
			return true;
		} else {
			client.Send(rrsp);
		}
		return false;
	}

	/**
	 * 留座
	 * @param client
	 * @return
	 */
	public synchronized boolean reservedSeat(LogicClient client, int type) {
		RuzuoRsp rrsp = new RuzuoRsp();
		rrsp.setIsok(3);
		LogicPlayer player = (LogicPlayer) getPlayer(client.getUserId());
		if(player != null && player.nextLiuzuoTimeType == -1 && player.liuZuoEndTime == 0) {
			boolean succBool = false;
			if(type == 0) {
				boolean freeSeatBool = false;
				XyClubInfo xyClubInfo = DataManager.getInstance().getMapClub().get(client.getClubid());
				if(xyClubInfo != null) {
					if(xyClubInfo.findPlayerXinyuValue(client.getUserId()) < this.gameStartMinScore) {
						freeSeatBool = true;
					}
				} else {
					if(client.getVo().getIntegral() < this.gameStartMinScore) {
						freeSeatBool = true;
					}
				}
				if(freeSeatBool && !this.listFreeSeat.contains(client.getUserId())) {
					succBool = true;
					this.listFreeSeat.add(client.getUserId());
				}
			} else if(type == 300 || type == 600) {
				if(client.getVo().getIntegral() >= type) {
					succBool = true;
					client.getVo().AddIntegral(-type);
				}
			} 
			if(succBool) {
				rrsp.setIsok(4);
				client.Send(rrsp);
				if(player.isReady()) {
					player.nextLiuzuoTimeType = type ;
				} else {
					BroadCastRuzuoRsp rsp = new BroadCastRuzuoRsp();
					player.liuZuoEndTime = System.currentTimeMillis() + (type == 0 ? 300 : type) * 1000;
					rsp.setSeatNo(type);
					rsp.setType(2);
					rsp.setUid(player.getUserId());
					BroadCast(rsp, 2);
				}
				return true;
			}
		} else {
			client.Send(rrsp);
		}
		return false;
	}
	/**
	 * 下局留座
	 */
	public void nextReservedSeat(LogicPlayer player) {
		BroadCastRuzuoRsp rsp = new BroadCastRuzuoRsp();
		player.liuZuoEndTime = System.currentTimeMillis() + (player.nextLiuzuoTimeType == 0 ? 300 : player.nextLiuzuoTimeType) * 1000;
		rsp.setSeatNo(player.nextLiuzuoTimeType);
		rsp.setType(2);
		rsp.setUid(player.getUserId());
		BroadCast(rsp, 2);
		player.nextLiuzuoTimeType = -1;
	}
	/**
	 * 回座
	 * @param client
	 * @return
	 */
	public synchronized boolean returnToSeat(LogicClient client) {
		RuzuoRsp rrsp = new RuzuoRsp();
		rrsp.setIsok(4);
		LogicPlayer player = (LogicPlayer) getPlayer(client.getUserId());
		if(player != null) {
			rrsp.setIsok(0);
			client.Send(rrsp);
			player.liuZuoEndTime = 0;
			BroadCastRuzuoRsp rsp = new BroadCastRuzuoRsp();
			rsp.setSeatNo(player.seatNo);
			rsp.setType(3);
			rsp.setUid(player.getUserId());
			BroadCast(rsp, 2);
			if(this.chexuanStatus == ChexuanTableStatus.READ) {
				bankerGameStart();
			}
			return true;
		} else {
			client.Send(rrsp);
		}
		return false;
	}

	public void bankerGameStart() {

	}
	/**
	 *  查 房主权限
	 * @param uid
	 * @return
	 */
	protected int checkBankerPower(int uid) {
		if(this.clubid > 0) {
			LogicClient client = (LogicClient) LogicServer.getInstance().getClient(uid);
			XyClubInfo clubInfo = DataManager.getInstance().getMapClub().get(client.getClubid());
			if(clubInfo != null) {
				int findPlayerManager = clubInfo.findPlayerManager(uid);
				return findPlayerManager;
			}
		} else if(uid == this.create.getBankerid()) {
			return 1;
		}
		return 3;
	}

	protected int nextSeatno(int seatNo) {
		return (seatNo + 1) % this.create.getGamesPeopleCount();
	}


	protected LogicPlayer getClientPlayer(int uid) {
		LogicPlayer player = (LogicPlayer) getPlayer(uid);
		if(player != null) {
			return player;
		}
		player = (LogicPlayer) this.getWatchWar().getPlayer(uid);
		return player;
	}
	public int random(int number) {
		Random r = new Random();
		return r.nextInt(number);
	}
	public void addListChat(String str) {
		if(this.listChat.size() > 15) {
			this.listChat.remove(0);
		}
		this.listChat.add(str);
	}
	//延时
	public void delayedOperate(LogicClient client) {
		GameDelayedRsp rsp = new GameDelayedRsp();
		rsp.setIsok(1);
		LogicPlayer player = (LogicPlayer) getPlayer(client.getUserId());
		if(this.operateTime > 1 && player != null && player.isReady() ) {
			rsp.setIsok(2);
			if(player.delayedCount < 6) {
				this.operateTime += 20;
				player.delayedCount ++;
				rsp.setIsok(0);
			}
		}
		if(rsp.getIsok().intValue() == 0) {
			BroadCast(rsp, 2);
		} else {
			client.Send(rsp);
		}
	}
	/**
	 * 房主关闭房间
	 */
	public boolean bankerCloseRoom(LogicClient client) {
		System.out.println("房主关闭房间getUserId:"+client.getUserId());

		System.out.println("this.create.getBankerid():"+this.create.getBankerid());
		if(client.getUserId() == this.create.getBankerid()) {
			this.bankerCloseBool = true;
			RoomMasterOperateRsp rsp = new RoomMasterOperateRsp();
			rsp.setIsok(0);
			rsp.setTempid(0);
			rsp.setType(0);
			BroadCast(rsp, 2);
			System.out.println("房主关闭房间getTable:"+client.getTable());
			return true;
		}
		return false;
	}
	/**
	 * 房主关闭聊天
	 * @param client
	 */
	public boolean bankerCloseChat(LogicClient client, int type) {
		if(client.getUserId() == this.create.getBankerid()) {
			this.forbidChat = type == 1;
			RoomMasterOperateRsp rsp = new RoomMasterOperateRsp();
			rsp.setIsok(0);
			rsp.setTempid(type);
			rsp.setType(1);
			BroadCast(rsp, 2);
			return true;
		}
		return false;
	}
	/**
	 * 房主踢人
	 * @param client
	 * @param uid
	 */
	public boolean bankerKickPeople(LogicClient client, int uid) {
		if(client.getUserId() != uid ) {
			int checkBankerPower = checkBankerPower(uid);
			int checkBankerPower_Banker = checkBankerPower(client.getUserId());
			if(checkBankerPower_Banker < checkBankerPower) {
				LogicClient tempClient = (LogicClient) LogicServer.getInstance().getClient(uid);
				if(leave(tempClient)) {
					if(tempClient.isLost()) {
						tempClient.Close();	
					}
				} else {
					LogicPlayer player = (LogicPlayer) getPlayer(uid);
					player.nextStandUpBool = true;
					player.bankerKickPeopleBool = true;
				}
				RoomMasterOperateRsp rsp = new RoomMasterOperateRsp();
				rsp.setIsok(0);
				rsp.setTempid(uid);
				rsp.setType(2);
				client.Send(rsp);
				this.listKickPeopleUids.add(uid);
				return true;
			}
		}
		return false;
	}
	/**
	 * 踢站起
	 * @param client
	 * @param uid
	 * @return
	 */
	public boolean bankerKickStandup(LogicClient client, int uid) {
		if(client.getUserId() != uid ) {
			int checkBankerPower = checkBankerPower(uid);
			int checkBankerPower_Banker = checkBankerPower(client.getUserId());
			if(checkBankerPower_Banker < checkBankerPower) {
				LogicPlayer player = (LogicPlayer) getPlayer(uid);
				if(!player.isReady()) {
					LogicClient tempClient = (LogicClient) LogicServer.getInstance().getClient(uid);
					standUp(tempClient);
				} else {
					player.nextStandUpBool = true;
				}
				RoomMasterOperateRsp rsp = new RoomMasterOperateRsp();
				rsp.setIsok(0);
				rsp.setTempid(uid);
				rsp.setType(3);
				client.Send(rsp);
				return true;
			}
		}
		return false;
	}
	/**
	 *  设置钵钵 需扣除的服务费
	 * @param bobo
	 * @return
	 */
	public int checkSetBoboValue(int bobo) {
		LogManager.getInstance().Log("需扣除的服务费:"+String.valueOf(bobo));
		int propValue = (int) (Integer.parseInt(DataManager.getInstance().systemValue("setbobotip"))/100.0 * bobo);
		LogManager.getInstance().Log("需扣除的服务费2222:"+String.valueOf(propValue));
		return propValue;
	}
	
	/**
	 * 牌局结束 计算俱乐部分红
	 */
	public void gameEndSendClubData() {

		ArrayList<TableUser> listUser = new ArrayList<TableUser>();
		for (Map.Entry<Integer, GamePlayerInfo> entry : mapRecord.entrySet()) {
			TableUser tUser = new TableUser();
			tUser.setBalance(entry.getValue().getUseBobo());
			tUser.setCid(entry.getValue().getClubid());
			tUser.setDairu(entry.getValue().getTotalBobo());
			tUser.setUid(entry.getKey());
			tUser.setShoushu(entry.getValue().getShoushu());
			listUser.add(tUser);
			int win = entry.getValue().getUseBobo() - entry.getValue().getTotalBobo();
			LogicClient client = (LogicClient) LogicServer.getInstance().getClient(entry.getKey());
			if (client!=null){
				if (win>0){
					client.getVo().addZongwinjucount();
				}
				if (win<0){
					client.getVo().addZongLosejuCount();
				}
			}else{
				if (win>0){
					UserVo.updateZongwinjuCount(entry.getKey());
				}
				if (win<0){
					UserVo.updateZongLosejuCount(entry.getKey());
				}
			}

		}

		TableUserInfo info = new TableUserInfo();
		info.setTableClubid(this.clubid);
		info.setTableNo(getID());
		info.setGamekey(getTableOnly());
		info.setTableUnionID(0);
		info.setTableUser(listUser);

		XyClubInfo xyClubInfo = DataManager.getInstance().getMapClub().get(this.clubid);
		if(xyClubInfo != null) {
			info.setTableUnionID(xyClubInfo.getUnionid());
			//俱乐部结算
			xyClubInfo.clubRecordSettlement(info);

			XyUnionInfo xyUnionInfo = DataManager.getInstance().getMapUnion().get(xyClubInfo.getUnionid());
			if(xyUnionInfo != null) {
				//联盟结算
				xyUnionInfo.unionRecordSettlement(info);
			}
		}
		//添加历史牌局
		XyGameLogDao.insertInto(getID(),getCreate().getBankerid(),getCreate().getRoomname(),getClubid(),getCreate().getDifen(),getCreate().getGameallTime(),listUser,getTableOnly());
	}
}
